﻿using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;
using UnityEngine.Events;

namespace Simulation.Framework.Editor
{
    public enum EScriptType
    {
        main,
        extend
    }

    public struct PanelCodeData
    {
        public string mainPath;
        public string extendPath;
        public MonoScript mainScript;
        public MonoScript extendScript;
    }

    public class PanelScriptsTreeViewItem : TreeViewItem
    {
        public PanelCodeData data;
        public EScriptType scriptType;
        public PanelScriptsTreeViewItem(int id, int depth, string displayName) : base(id, depth, displayName) { }
    }

    // 脚本文件树状图
    public class PanelScriptsTreeView : TreeView
    {
        public UnityAction<PanelCodeData> onItemSingleClciked;

        public PanelScriptsTreeView(TreeViewState state, MultiColumnHeader multiColumnHeader) : base(state, multiColumnHeader)
        {
            rowHeight = 20;
            showBorder = true;
            Reload();
        }

        // 创建根节点
        protected override TreeViewItem BuildRoot()
        {
            return new TreeViewItem { id = 0, depth = -1 };
        }

        // 创建每行元素数据
        protected override IList<TreeViewItem> BuildRows(TreeViewItem root)
        {
            var rows = GetRows() ?? new List<TreeViewItem>();
            rows.Clear();

            string[] guids = AssetDatabase.FindAssets("t:Script");
            for (int i = 0; i < guids.Length; i++)
            {
                string guid = guids[i];
                string path = AssetDatabase.GUIDToAssetPath(guid);
                MonoScript script = AssetDatabase.LoadAssetAtPath<MonoScript>(path);
                Type panelType = script.GetClass();
                if (panelType != null)
                {
                    // 判断是否是页面脚本
                    if (panelType.BaseType == typeof(PanelBase))
                    {
                        PanelScriptsTreeViewItem panelScriptsTreeViewItem_Main = CreateTreeViewItem(root,script, path, rows);
                    }
                }
            }

            // 为每一个 item 设置设置深度值
            SetupDepthsFromParentsAndChildren(root);
            return rows;
        }

        // 单击 item
        protected override void SingleClickedItem(int id)
        {
            base.SingleClickedItem(id);
            PanelScriptsTreeViewItem item = FindItem(id, rootItem) as PanelScriptsTreeViewItem;
            PanelCodeData scriptData = SelectedScriptData(item);
            onItemSingleClciked?.Invoke(scriptData);
        }

        // 双击 item
        protected override void DoubleClickedItem(int id)
        {
            base.DoubleClickedItem(id);
            PanelScriptsTreeViewItem item = FindItem(id, rootItem) as PanelScriptsTreeViewItem;
            Selection.activeObject = item.data.mainScript;
            EditorGUIUtility.PingObject(item.data.mainScript);
        }

        // 右击
        protected override void ContextClicked()
        {
            base.ContextClicked();

            // 右击菜单
            GenericMenu menu = new GenericMenu();
            menu.AddItem(new GUIContent("添加脚本"),false, CreateScripts);
            //menu.AddItem(new GUIContent("删除脚本"),false, DeleteScripts);
            menu.ShowAsContext();
        }

        private PanelScriptsTreeViewItem CreateTreeViewItem(TreeViewItem root, MonoScript script, string path, IList<TreeViewItem> rows)
        {
            string displayName = Path.GetFileNameWithoutExtension(path);
            int guid = script.GetInstanceID();

            PanelCodeData data = new PanelCodeData();
            data.mainPath = path;
            data.mainScript = script;

            string folder = Path.GetDirectoryName(path);
            string fileName = Path.GetFileNameWithoutExtension(path);
            string extendPath = folder + "/" + fileName + "_extend.cs";
            data.extendPath = extendPath;

            // MonoScript
            MonoScript extendScript = AssetDatabase.LoadAssetAtPath<MonoScript>(extendPath);
            data.extendScript = extendScript;

            PanelScriptsTreeViewItem treeViewItem = new PanelScriptsTreeViewItem(guid, -1, displayName);
            treeViewItem.scriptType = EScriptType.main;
            treeViewItem.icon = FindIcon("cs Script Icon") as Texture2D;
            treeViewItem.data = data;
            root.AddChild(treeViewItem);
            rows.Add(treeViewItem);

            // 展开
            if (IsExpanded(treeViewItem.id))
            {
                // extend
                if (extendScript == null)
                    Debug.LogError("扩展文件丢失：" + data.extendPath);
                else
                {
                    displayName = Path.GetFileNameWithoutExtension(extendPath);
                    guid = extendScript.GetInstanceID();

                    data = new PanelCodeData();
                    data.mainPath = extendPath;
                    data.extendPath = extendPath;
                    data.mainScript = extendScript;
                    data.extendScript = extendScript;

                    PanelScriptsTreeViewItem extendItem = new PanelScriptsTreeViewItem(guid, -1, displayName);
                    extendItem.data = data;
                    extendItem.scriptType = EScriptType.extend;
                    extendItem.icon = FindIcon("cs Script Icon") as Texture2D;
                    treeViewItem.AddChild(extendItem);
                    rows.Add(extendItem);
                }
            }
            else
            {
                treeViewItem.children = CreateChildListForCollapsedParent();
            }
            return treeViewItem;
        }

        /// <summary>
        /// 创建 title
        /// </summary>
        public static MultiColumnHeaderState CreateDefaultMultiColumnHeaderState(float treeViewWidth)
        {
            MultiColumnHeaderState.Column[] columns = new MultiColumnHeaderState.Column[]
            {
                new MultiColumnHeaderState.Column
                {
                    headerContent = new GUIContent("类", "所有的 UI 类"),
                    headerTextAlignment = TextAlignment.Center,
                    sortedAscending = true,
                    sortingArrowAlignment = TextAlignment.Center,
                    width = treeViewWidth,
                    minWidth = 60,
                    autoResize = true,
                    allowToggleVisibility = false
                }
            };

            return new MultiColumnHeaderState(columns);
        }

        private Texture FindIcon(string iconName)
        {
            return EditorGUIUtility.IconContent(iconName).image;
        }

        private void CreateScripts()
        {
            WindowHelper.GetCreatePanelWindow();
        }

        private void DeleteScripts()
        {
            Debug.Log("暂不支持删除");
        }

        private void GetClass(MonoScript script,string path,out Type type,out bool isExtend)
        {
            type = default(Type);
            isExtend = false;

            Type panelType = script.GetClass();

            if (panelType == null)
            {
                // 判断是否是 控件的 扩展
                string folder = Path.GetDirectoryName(path);
                string fileName = Path.GetFileName(path);
                if (fileName.Contains("_Extend"))
                {
                    string newPath = folder + fileName.Replace("_Extend", "");
                    script = AssetDatabase.LoadAssetAtPath<MonoScript>(newPath);
                    panelType = script.GetClass();
                    type = panelType;
                    isExtend = script != null && panelType != null;
                }
            }

            if (panelType.BaseType == typeof(PanelBase))
            {
                type = panelType;
            }
        }

        private Type SelectedScript(PanelScriptsTreeViewItem item)
        {
            // 如果是扩展类型，则指向其父类
            if (item.scriptType == EScriptType.extend)
                item = item.parent as PanelScriptsTreeViewItem;
            return item.data.mainScript.GetClass();
        }

        private PanelCodeData SelectedScriptData(PanelScriptsTreeViewItem item)
        {
            // 如果是扩展类型，则指向其父类
            if (item.scriptType == EScriptType.extend)
                item = item.parent as PanelScriptsTreeViewItem;
            return item.data;
        }
    }
}